import * as ol from 'ol'
import * as Geom from 'ol/geom';
import { defaults as interactionDefaults_ } from 'ol/interaction';
import * as Interaction from 'ol/interaction';
import { defaults as controlDefaults_ } from 'ol/control';
import Control from 'ol/control';
import Layer  from 'ol/layer/Layer';
import * as Source from 'ol/source';
import * as Style from 'ol/style';
import * as Format from 'ol/format';
import * as olProj from 'ol/proj';
import TileGrid from 'ol/tilegrid/TileGrid';
import * as olSphere from 'ol/sphere';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import XYZSource from 'ol/source/XYZ';
import TileImageSource from 'ol/source/TileImage';
import Cluster from 'ol/source/Cluster'
import { Fill, Stroke,  Icon, Circle, Text } from 'ol/style'
import { boundingExtent, getCenter } from 'ol/extent'

// let geom_
// let interaction_
// let control_
// let source_
// let style_
// let format_

// Geom = geom_;
// Interaction = interaction_;
// Control = control_;
// Source = source_;
// Style = style_;
// Format = format_;
/**
 * @class
 * @param {Object} [options] - 初始化参数配置
 * @param {Array<Layer>} [options.planimetricLayers = Zs.tiandituLayers] - 平面地图
 * @param {Array<Layer>} [options.satelliteLayers = Zs.tiandituLayers] - 卫星地图
 * @param {Layer} [options._25Dlayer] - 2.5维地图
 * @param {String} [options.target = map] - 字符串选择器,地图挂载的div
 * @param {Array<number>} [options.center] - 地图初始化时显示的中心点
 * @param {Int} [options.zoom = 10] - 地图初始显示层级
 * @param {Int} [options.maxZoom = 19] - 地图允许显示的最小层级
 * @param {Int} [options.minZoom = 1] - 地图允许显示的最大层级
 * @param {Array<Interaction>} [options.interactions] - 地图交互功能
 * @param {Array<Control>} [options.controls] - 地图需要显示的控件
 * @param {(String | Boolean)} [options.logo = false] - 是否需要显示logo
 * @param {String} [options.projection = EPSG:3857] - 地图投影方式
 * @param {Boolean} [options.showPlanimetric = true] - 是否显示平面地图
 * @param {Boolean} [options.show_25D = true] - 是否显示2.5维地图
 * @param {Function} [options.pointermove] - 是否开启鼠标移动事件的绑定
 * @param {Function} [options.click] - 是否绑定地图的点击事件
 * @param {Function} [options.dblclick] - 是否绑定地图的双击事件
 * @param {Function} [options.zoomEvent] - 是否绑定zoom事件
 *
 * @property {Array<Layer>} planimetricLayers - 平面地图
 * @property {Array<Layer>} satelliteLayers - 卫星地图
 * @property {Layer} _25Dlayer - 2.5维地图
 * @property {Boolean} showPlanimetric - 默认为true
 * @property {Boolean} show_25D - 默认为true
 * @property {Format.WKT} format - wkt格式化工具
 */
var defaultIcon = require("../assets/map/goal1.png");
var config = {
  target: 'map',
  center: [121.350267,31.204433],
  zoom: 10,
  maxZoom: 19,
  minZoom: 1,
  interactions: function() {
    return [];
  },
  controls: function() {
    return [];
  },
  logo: false,
  projection: 'EPSG:4326',
  showPlanimetric: true,
  show_25D: false,
  style: {
    // zs.Map.addfeatures里的默认配置
    featureImg: {
      scale: 1,
      size: [19, 33],
      anchor: [0.5, 1],
      img: defaultIcon
    },
    // zs.Map._initDraw里的默认配置,鼠标吸附样式配置
    drawImg: {
      cursorUrl: "url("+defaultIcon+") 9.5 33,auto",
      scale: 1,
      size: [19, 33],
      anchor: [0.5, 1],
      img: defaultIcon
    }
  },
  planimetricLayers: function() {
    return Zs.tiandituLayers('planimetric','c');
  },
  satelliteLayers: function() {
    return Zs.tiandituLayers('satellite','c');
  },
  _25DLayer: function() {
    return new TileLayer({
      source: new XYZSource({
        url: 'http://10.0.7.205:8080/chaoyan/{z}/{x}/{y}.png'
      })
    });
  }
}

function Zs(options) {
  options = options || {};
  this.planimetricLayers = options.planimetricLayers || config.planimetricLayers();
  this.satelliteLayers = options.satelliteLayers || config.satelliteLayers();
  this._25DLayer = options._25DLayer || config._25DLayer();
  options.target = options.target || config.target;
  options.center = options.center || config.center;
  options.zoom = options.zoom || config.zoom;
  options.maxZoom = options.maxZoom || config.maxZoom;
  options.minZoom = options.minZoom || config.minZoom;
  options.interactions = options.interactions || config.interactions();
  options.controls = options.controls || config.controls();
  options.logo = options.logo || config.logo;
  options.projection = options.projection || config.projection;
  options.extent = options.extent || config.extent;
  this.showPlanimetric = options.showPlanimetric || config.showPlanimetric;
  this.show_25D = options.show_25D || config.show_25D;

  this.format = new Format.WKT();
  this.init(options);
  this.initEvent(options);
}

/**
 * 创建地图,设置图层属性及显示与隐藏,平面地图index=20,卫星地图index=10,2.5维index=30
 * @function
 */
Zs.prototype.init = function(options) {
  var that = this;
  var layers = [];
  this.planimetricLayers.forEach(function(v, k) {
    layers.push(v);
    v.setZIndex(20);
    !that.showPlanimetric && v.setVisible(false);
  })
  this.satelliteLayers.forEach(function(v, k) {
    layers.push(v);
    v.setZIndex(10);
    that.showPlanimetric && v.setVisible(false);
  })
  if (this._25DLayer) {
    layers.push(that._25DLayer);
    that._25DLayer.setZIndex(30);
    !that.show_25D && that._25DLayer.setVisible(false);
  }

  this.map = new ol.Map({
    interactions: interactionDefaults_().extend(options.interactions),
    layers: layers,
    // 设置显示地图的视图
    view: new ol.View({
      projection: options.projection,
      center: options.center,
      zoom: options.zoom,
      maxZoom: options.maxZoom,
      minZoom: options.minZoom,
      extent: options.extent
    }),
    controls: controlDefaults_({
      attribution: false,
      rotate: false,
      zoom: false
    }),
    logo: options.logo,
    target: options.target
  });
};

/**
 * 天地图图层创建
 * @function Zs.tiandituLayers
 * @param {String} - 值为satellite或者planimetric或者任意参数: satellite表示创建卫星地图，planimetric表示创建平面地图，传任意参数表示都创建
 * @param {String} - 值为w或者c,w代表3857(900913),c代表4326
 * @description vec请求的是二维地图，cva请求的是二维地图的标注，img请求的是卫星地图，cia请求的是卫星地图标注
 */
Zs.tiandituLayers = function(type, unit) {
  var types;
  var layers = [];
  if (type === 'satellite') {
    types = ['img', 'cia'];
  } else if (type === 'planimetric') {
    types = ['vec', 'cva'];
  } else {
    types = ['img', 'cia', 'vec', 'cva'];
  }
  var projection = unit === 'w' ? 'EPSG:3857' : 'EPSG:4326';
  for (var i = 0; i < types.length; i++) {
    layers.push(
      new TileLayer({
        source: new XYZSource({
          url: 'http://t{0-7}.tianditu.gov.cn/DataServer?T=' + types[i] + '_' + unit + '&x={x}&y={y}&l={z}&tk=d2e283e434acd4159537e5f3155f2e11',
          projection: projection
        })
      })
    );
  }
  return layers;
};

/**
 * 高德地图图层创建
 * @function Zs.gaodeLayers
 * @param {String} type - 值为satellite或者planimetric或者任意参数: satellite表示创建卫星地图，planimetric表示创建平面地图，传任意参数表示都创建
 * @description types中的值：7代表平面地图，6代表卫星地图，8代表卫星地图标注;url的值：webrd0字体较小,但是是旧地图；webst0字体较大；wprd0最新,加上ltype=3为无字幕
 */
Zs.gaodeLayers = function(type) {
  var types;
  var layers = [];
  if (type === 'satellite') {
    types = [6, 8];
  } else if (type === 'planimetric') {
    types = [7];
  } else {
    types = [6, 8, 7];
  }
  for (var i = 0; i < types.length; i++) {
    layers.push(
      new TileLayer({
        source: new XYZSource({
          url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&ltype=7&style=' + types[i] + '&x={x}&y={y}&z={z}'
        })
      })
    );
  }
  return layers;
};
/**
 * 百度地图图层创建
 * @function Zs.baiduLayers
 * @param {String} type - 值为satellite或者planimetric或者任意参数: satellite表示创建卫星地图，planimetric表示创建平面地图，传任意参数表示都创建
 * @description url中的p参数为0无字幕，为1有字幕；scaler=1尺寸为256,2为512
 */
Zs.baiduLayers = function(type) {
  var resolutions = [];
  var layer = [];
  for (var i = 0; i < 20; i++) {
    resolutions[i] = Math.pow(2, 19 - i);
  }
  var tilegrid = new TileGrid.TileGrid({
    origin: [0, 0],
    resolutions: resolutions
  });
  if (type === 'satellite') {
    var satellite = new TileLayer({
      source: new TileImageSource({
        projection: 'EPSG:3857',
        tileGrid: tilegrid,
        tileUrlFunction: function(tileCoord, pixelRatio, proj) {
          var data = Zs.baiduUrlHandle(tileCoord);
          return 'http://shangetu' + data.line + '.map.bdimg.com/it/u=x=' + data.x + ';y=' + data.y + ';z=' + data.z + ';v=009;type=sate&fm=46&udt=20150504&app=webearth2&v=009&udt=20150601';
        }
      })
    });
    var satelliteBz = new TileLayer({
      source: new TileImageSource({
        projection: 'EPSG:3857',
        tileGrid: tilegrid,
        tileUrlFunction: function(tileCoord, pixelRatio, proj) {
          var data = Zs.baiduUrlHandle(tileCoord);
          return 'http://online' + data.line + '.map.bdimg.com/onlinelabel/?qt=tile&x=' + data.x + '&y=' + data.y + '&z=' + data.z + '&styles=sl&udt=20160928&scaler=1&p=1';
        }
      })
    });
    layer.push(satellite, satelliteBz);
  } else if (type === 'planimetric') {
    var planimetric = new TileLayer({
      source: new TileImageSource({
        projection: 'EPSG:3857',
        tileGrid: tilegrid,
        tilePixelRatio: 2, // 采用512的尺寸，不然图形变形厉害
        tileUrlFunction: function(tileCoord, pixelRatio, proj) {
          var data = Zs.baiduUrlHandle(tileCoord);
          return 'http://online' + data.line + '.map.bdimg.com/onlinelabel/?qt=tile&x=' + data.x + '&y=' + data.y + '&z=' + data.z + '&styles=pl&udt=20160928&scaler=2&p=1';
        }
      })
    });
    layer.push(planimetric);
  }
  return layer;
};
/**
 * 百度切片计算算法
 * @function Zs.baiduUrlHandle
 */
Zs.baiduUrlHandle = function(tileCoord) {
  if (!tileCoord) {
    return '';
  }
  var z = tileCoord[0];
  var x = tileCoord[1];
  var y = tileCoord[2];

  if (x < 0) {
    x = 'M' + (-x);
  }
  if (y < 0) {
    y = 'M' + (-y);
  }
  var line = Math.ceil(Math.random() * 4);
  return { line: line, x: x, y: y, z: z };
};

/**
 * 谷歌地图图层
 * @function Zs.googleLayers
 * @param {String} type - 值为satellite或者planimetric或者任意参数: satellite表示创建卫星地图，planimetric表示创建平面地图
 * @description 谷歌地图备用地址
 * http://ditu.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i366037870!3m9!2szh-CN!3sCN!5e18!12m1!1e50!12m3!1e37!2m1!1ssmartmaps!4e0
 * http://mt0.google.cn/maps/vt?lyrs=s@702&hl=zh-CN&gl=CN&&x=22&y=12&z=5
 * http://mt{1-3}.google.cn/vt/lyrs=s@123&hl=zh-CN&gl=CN&src=app&&x=${x}&y=${y}&z=${z}  旧版 卫星图层
 * http://mt{1-3}.google.cn/vt/imgtp=png32&lyrs=h@205000000&hl=zh-CN&gl=CN&src=app&&x=${x}&y=${y}&z=${z}  旧版  标注图层
 * http://mt{1-3}.google.cn/vt/lyrs=m@205000000&hl=zh-CN&gl=CN&src=app&&x=${x}&y=${y}&z=${z}  旧版   矢量图层
 * http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0
 */
Zs.googleLayers = function(type) {
  var layer = []
  if (type === 'satellite') {
    var satellite = new TileLayer({
      source: new XYZSource({
        url: 'http://mt{1-3}.google.cn/vt/lyrs=s@123&hl=zh-CN&src=app&gl=CN&x={x}&y={y}&z={z}'
      })
    });
    var satelliteBz = new TileLayer({
      source: new XYZSource({
        url: 'http://ditu.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i366037870!3m9!2szh-CN!3sCN!5e18!12m1!1e50!12m3!1e37!2m1!1ssmartmaps!4e0'

      })
    });
    layer.push(satellite, satelliteBz);
  } else if (type === 'planimetric') {
    var planimetric = new TileLayer({
      source: new XYZSource({
        url: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'

      })
    });
    layer.push(planimetric);
  }
  return layer;
};

Zs.prototype.guid = function() {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4());
}

/**
 * 初始化地图相关事件
 */
Zs.prototype.initEvent = function(options) {
  if (options.pointermove instanceof Function) {
    this.bindPointermove(options.pointermove);
  }
  if (options.click instanceof Function) {
    this.bindClick(options.click);
  }
  if (options.dblclick instanceof Function) {
    this.bindDblclick(options.dblclick);
  }
  if (options.zoomEvent instanceof Function) {
    this.bindZoom(options.zoomEvent);
  }
}

/**
 * 绑定鼠标移入移出事件
 */
Zs.prototype.bindPointermove = function(pointermove) {
  var that = this;
  var oldFeatures = {};
  that.map.on('pointermove', function(event) {
    pointermove(event);

    var newFeatures = {};
    var dispatchFeatures = {};
    that.map.forEachFeatureAtPixel(event.pixel, function(feature) {
      newFeatures[feature.getId()] = feature;
      dispatchFeatures[feature.getId()] = feature;
    });
    Object.keys(oldFeatures).forEach(function(v, k) {
      if (!v) {
        console.log('地图移入移出事件中的feature的id出现问题');
        return;
      }
      if (!newFeatures[v]) {
        // 删除旧的feature,并触发移出事件
        oldFeatures[v].dispatchEvent({ type: 'mouseOut', event: event });
        delete oldFeatures[v];
      } else {
        // 删除已经触发过事件的feature
        delete dispatchFeatures[v];
      }
    });
    Object.keys(dispatchFeatures).forEach(function(v, k) {
      dispatchFeatures[v].dispatchEvent({ type: 'mouseIn', event: event });
    })
    oldFeatures = newFeatures;
  });
}

/**
 * 绑定鼠标单击事件
 */
Zs.prototype.bindClick = function(singleclick) {
  var that = this;
  that.map.on('singleclick', function(event) {
    singleclick(event);
    that.map.forEachFeatureAtPixel(event.pixel, function(feature) {
      feature.dispatchEvent({ type: 'click', event: event });
      return true;
    });
  })
}

/**
 * 绑定鼠标双击事件
 */
Zs.prototype.bindDblclick = function(dblclick) {
  var that = this;
  that.map.on('dblclick', function(event) {
    dblclick(event);
    that.map.forEachFeatureAtPixel(event.pixel, function(feature) {
      feature.dispatchEvent({ type: 'dblclick', event: event });
    });
  })
}

/**
 * 绑定zoom事件
 */
Zs.prototype.bindZoom = function(zoomEvent) {
  var that = this;
  that.map.getView().on('change:resolution', function(event) {
    zoomEvent(event);
  });
}

Zs.prototype.goTo = function(lonlat){
  if(typeof(lonlat) == 'string'){
    this.map.getView().setCenter(this.format.readFeature(lonlat).getGeometry().getCoordinates());
  }else if(lonlat instanceof Geom.Point){
    this.map.getView().setCenter(lonlat.getGeometry().getCoordinates());
  }
}

/**
 * 添加要素
 * @function
 * @param {Array<Object>} data - 数据列表,每一行都可具有options的属性
 * @param {Object} [options] - 坐标要素渲染配置
 * @param {Layer} [options.layer] - 承载要素的图层
 * @param {String} [options.fillColor] - 图层和要素的填充颜色
 * @param {String} [options.strokeColor] - 图层和要素的描边颜色
 * @param {String} [options.strokeWidth] - 图层和要素的描边宽度
 * @param {Boolean} [options.isShowText] - 是否显示要素的名称,名称根据数据列表的name属性
 * @param {String} [options.textFillColor] - 要素显示的名称填充颜色
 * @param {String} [options.textStrokeColor] - 要素显示的名称描边颜色
 * @param {String} [options.textStrokeWidth] - 要素显示的名称描边宽度
 * @param {String} [options.textFontSize] - 要素显示的名称字体
 * @param {Boolean} [options.isShowImg] - 是否显示图标,图标根据数据列表的img属性或者options.img
 * @param {Int} [options.imgScale] - 缩放比例,默认1
 * @param {Array<Int>} [options.imgSize] - 图标的宽高比
 * @param {Array<Int>} [options.imgAnchor] - 图标上下左右的位置偏移
 * @param {String} [options.img] - 图标地址
 * @param {String} [options.action = add] - 要素要以怎样的添加方式,参数包括'add'(追加),'new'(去掉之前的数据添加新数据)
 * @param {Object} [options.transform = {}] - 数据列表按怎么的投影方式转换,数据格式:{dataProjection:'EPSG:4326',featureProjection:'EPSG:3857'}
 * @param {Boolean} [options.featureStyleFalse] - 此属性废弃，改用isSetStyle
 * @param {Boolean} [options.isSetStyle] - 是否设置要素的样式，默认可以设置样式，不设置样式必须把此项置为false
 * @param {Boolean} [options.isSetDefaultEvent] - 是否开启feature的鼠标移动默认事件
 * @param {Function} [options.mouseIn] - 鼠标移入事件
 * @param {Function} [options.mouseOut] - 鼠标移出事件
 * @param {Function} [options.click] - 鼠标点击事件
 * @param {Function} [options.dblclick] - 鼠标双击事件
 * @returns {Object} data - 包含当前图层及要素,{layer:'',features:''}
 */
Zs.prototype.addFeatures = function(data, options) {
  var that = this;
  options = options || {};
  var layer = options.layer;
  var textFontSize = options.textFontSize || '16px monospace';
  var action = options.action || 'add';
  // var transform = options.transform || {};
  var isSetStyle = options.featureStyleFalse;
  if (isSetStyle !== false) {
    isSetStyle = options.isSetStyle;
  }
  var features = [];
  if (data instanceof Array) {
    var styleOptions = {};
    for (var i = 0; i < data.length; i++) {
      var feature;
      if (data[i].feature) {
        feature = data[i].feature;
      } else if (options.isGeom && data[i].geom) {
        feature = this.format.readFeature(data[i].geom);
      } else if (data[i].lonlat) {
        feature = this.format.readFeature(data[i].lonlat);
      } else {
        continue;
      }

      if(data[i].id) feature.set("id",data[i].id);
      if(data[i].name) feature.set("name",data[i].name);
      //feature.setId(that.guid());
      features.push(feature);

      if (isSetStyle !== false) {
        if (data[i].style) { // 如果feature自带样式，直接设置
          feature.setStyle(data[i].style);
          continue;
        }
        if (options.isGeom) {
          styleOptions = { // 设置feature的样式
            fill: new Style.Fill({
              color: data[i].fillColor || options.fillColor
            }),
            stroke: new Style.Stroke({
              width: data[i].strokeWidth || options.strokeWidth,
              color: data[i].strokeColor || options.strokeColor
            })
          };
        }

        if (options.isShowText || data[i].isShowText) {
          var textData = JSON.parse(JSON.stringify(data[i]));
          var databak = JSON.parse(JSON.stringify(data[i]));
          // if(options.textField){
          //   if(options.textField.indexOf('.') !== -1){
          //     var textArr = options.textField.split('.');
          //     var n = 0;
          //     while(n < textArr.length){
          //       textData = textData[textArr[n]];
          //       n++;
          //     }
          //   }else{
          //     textData = textData[options.textField]
          //   }
          // }else{
          //   textData = textData.name
          // }
          textData = textData.name
          data[i] = databak;
          styleOptions.text = new Style.Text({
            textAlign: 'center',
            textBaseline: 'middle',
            font: textFontSize,
            text: textData,
            offsetY: options.offsetY ? options.offsetY : 0,
            fill: new Style.Fill({
              color: data[i].textFillColor || options.textFillColor
            }),
            stroke: new Style.Stroke({
              color: data[i].textStrokeColor || options.textStrokeColor,
              width: data[i].textStrokeWidth || options.textStrokeWidth
            })
          })
        }
        if (options.isShowImg || data[i].isShowImg) {
          styleOptions.image = new Style.Icon({
            scale: data[i]['imgScale'] || options.imgScale || config.style.featureImg.scale,
            size: data[i]['imgSize'] || options.imgSize || config.style.featureImg.size,
            anchor: data[i]['imgAnchor'] || options.imgAnchor || config.style.featureImg.anchor,
            src: data[i]['img'] || options.img || config.style.featureImg.img
          })
        }

        var style = new Style.Style(styleOptions);
        feature.setStyle(style);
        this.featureStyle = style

        // 设置默认鼠标移入移出事件
        if (options.isSetDefaultEvent) {
          feature.on('mouseIn', function() {
            var style = new Style.Style({
              fill: new Style.Fill({
                color: 'yellow'
              }),
              stroke: new Style.Stroke({
                width: 4,
                color: 'red'
              })
            })
            feature.setStyle(style);
          })
          feature.on('mouseOut', function() {
            feature.setStyle(style);
          })
        }
        // 绑定feature事件
        if (options.mouseIn instanceof Function) {
          feature.on('mouseIn', function(e) {
            options.mouseIn(e);
          })
        }
        if (options.mouseOut instanceof Function) {
          feature.on('mouseOut', function(e) {
            options.mouseOut(e);
          })
        }
        if (options.click instanceof Function) {
          feature.set("click",options.click)
          feature.on('click', function(e) {
            options.click(e);
          })
        }
        if (options.dblclick instanceof Function) {
          feature.on('dblclick', function(e) {
            options.dblclick(e);
          })
        }
      }
    }
  }

  if(options.addToLayer!==false){
    if (layer) {
      var source = layer.getSource();
      if (action === 'new') source.clear();
      source.addFeatures(features);
    } else {
      layer = new VectorLayer({
        // declutter: true,
        source: new VectorSource({
          features: features
        })
      });
      layer.setZIndex(900);
      this.map.addLayer(layer);
    }  
  }


  return {
    layer: layer,
    features: features
  };
}

// 添加聚合
Zs.prototype.addCluster = function (features) {
  let that = this
  this.removeCluster()
  // 创建几个聚合效果所在的点
  const source = new VectorSource({
    features: features
  })
  // Cluster聚合类
  const clusterSource = new Cluster({
    // distance: 20, // 聚合点与点之间的距离
    minDistance: 15, // 聚合点与点之间的最小距离
    source: source
  })
  // 聚合图层
  this.clustersLayer = new VectorLayer({
    source: clusterSource,
    // 聚合样式
    style: function (feature) {
      // 点的个数
      const size = feature.get('features').length
      if(size>1){
        console.log(feature.get('features'));
        return new Style.Style({
          image: new Circle({ // 圆形
            radius: 15, // 半径
            stroke: new Stroke({ // 边框
              color: '#fff'
            }),
            fill: new Fill({ // 填充
              color: '#3399CC'
            })
          }),
          text: new Text({ // 文字样式
            font: '15px sans-serif',
            text: size.toString(),
            fill: new Fill({
              color: '#fff'
            })
          })
        })
      }else{
        return feature.get('features')[0].getStyle()
      }

    }
  })
  this.clustersLayer.setZIndex(1000)
  this.map.addLayer(this.clustersLayer)
  // 地图添加点击事件
  this.map.on('click', this.clusterClickHandle.bind(this))
}
// 清除聚合
Zs.prototype.removeCluster = function () {
  if (this.clustersLayer) {
    this.map.removeLayer(this.clustersLayer)
    this.clustersLayer = null
  }
  // 解除点击事件
  this.map.un('click', this.clusterClickHandle.bind(this))
},
// 聚合点击效果处理函数
Zs.prototype.clusterClickHandle = function (e) {
  this.clustersLayer.getFeatures(e.pixel).then((clickedFeatures) => {
    if (clickedFeatures.length) {
      const features = clickedFeatures[0].get('features')
      // 点的个数大于1才有效果
      if (features.length > 1) {
        const extent = boundingExtent(
          features.map((r) => r.getGeometry().getCoordinates())
        )
        let [width, height] = this.map.getSize()
        width = Math.ceil(width)
        height = Math.ceil(height / 5)
        // 定位到点击位置
        this.map.getView().fit(extent, {duration: 500, padding: [height, width, height, width + 500]})
      }else{
        features[0].get("click")({target:features[0]})
      }
    }
  })
}



/**
 * @deprecated
 * 将某个坐标转为当前的坐标系的坐标;
 * 此方法现在支持3857和4326两种坐标系的转换
 * 大部分国土的地图使用的北京54或者西安80是无法使用此方法的
 * {Array} 传入的要转换的坐标点
 */
Zs.prototype.transformLonlatToCurProjection = function(lonlat) {
  var point;
  if (lonlat[0].toString().indexOf('.') < 5 && this.map.get('projection') === 'EPSG:3857') {
    point = olProj.transform(lonlat, 'EPSG:4326', 'EPSG:3857');
  } else if (lonlat[0].toString().indexOf('.') >= 5 && this.map.get('projection') === 'EPSG:4326') {
    point = olProj.transform(lonlat, 'EPSG:3857', 'EPSG:4326');
  } else {
    console.log('坐标系转换失败，当前地图坐标系不为3857或者4326,当前坐标为：' + lonlat);
  }
  return point;
}

/**
 * 将4326的坐标的经度转为3857的坐标
 * @function
 * @param {Number} lon - 经度
 */
Zs.prototype.transformLonTo3857 = function($lon) {
  $lon = $lon * 2 - $lon;
  $lon *= 20037508.34 / 180;
  $lon = Math.round($lon, 6);
  return $lon;
}
/**
 * 将4326的坐标的纬度转为3857的坐标
 * @function
 * @param {Number} lat - 纬度
 */
Zs.prototype.transformLatTo3857 = function($lat) {
  $lat = $lat * 2 - $lat;
  $lat = Math.log(Math.tan((90 + $lat) * Math.PI / 360)) / (Math.PI / 180);
  $lat *= 20037508.34 / 180;
  $lat = Math.round($lat, 7);
  return $lat;
}

/**
 * 获取当前屏幕的四个角的多边形
 */

Zs.prototype.getCurrentPolygon = function() {
  return this.format.writeGeometry(new Geom.Polygon.fromExtent(this.map.getView().calculateExtent()));
}

/**
 * 把圆形变成多边形
 * @param {Object} options
 * @param {Array} [options.center] - 圆心
 * @param {Int} [options.radius] - 圆半径
 * @param {Int} [options.step] - 步长，生成多少个坐标点，默认为1，返回360个坐标点，设置为10，返回36个坐标点
 * @param {Project} [options.sourceProjection] - 中心点数据的投影类型，默认4326
 * @param {Project} [options.destProjection] - 生成的多边形的投影类型，默认4326
 */
Zs.prototype.getCirclePolygon = function(options) {
  var center = options.center;
  var radius = options.radius;
  var step = options.step || 1;
  var sourceProjection = options.sourceProjection || 'EPSG:4326';
  var destProjection = options.destProjection || 'EPSG:4326';
  if (sourceProjection === 'EPSG:4326') {
    center = olProj.transform(center, 'EPSG:4326', 'EPSG:3857');
  }

  var polygonArr = [];
  for (var i = 0; i < 360; i = i + step) {
    var x1 = center[0] + radius * Math.cos(i * Math.PI / 180);
    var y1 = center[1] + radius * Math.sin(i * Math.PI / 180);
    if (destProjection === 'EPSG:4326') {
      var point = olProj.transform([x1, y1], 'EPSG:3857', 'EPSG:4326');
      polygonArr.push([point[0].toFixed(6), point[1].toFixed(6)]);
    } else {
      polygonArr.push([x1.toFixed(2), y1.toFixed(2)]);
    }
  }
  polygonArr.push(polygonArr[0]);

  return this.format.writeGeometry(new Geom.Polygon([polygonArr]));
}

/**
 * 创建提示tip
 * @function
 * @param {Object} options - tooltip的配置
 * @param {Dom} [options.element] - 提示的div
 * @param {String} [options.classname = map-tooltip] - 提示div的样式
 * @param {Array<Int>} [options.offset = [15,0]] - tip的偏移位置
 * @param {String} [options.position = center-left] - tip显示的位置
 * @param {Dom} [tooltipElement] - 提示的div,传入此参数表示需要清除此dom
 * @returns {Object} data - 返回创建的tip元素
 */
Zs.prototype.createTooltip = function(options, tooltipElement) {
  options = options || {};
  if (tooltipElement) {
    tooltipElement.parentNode.removeChild(tooltipElement);
  }
  if (!options.element) {
    tooltipElement = document.createElement('div');
    tooltipElement.className = options.classname || 'map-tooltip hidden';
  } else {
    tooltipElement = options.element;
  }
  var tooltip = new ol.Overlay({
    element: options.element || tooltipElement,
    offset: options.offset || [15, 0],
    positioning: options.position || 'center-left'
  });
  this.map.addOverlay(tooltip);
  return { element: tooltipElement, tooltip: tooltip }
}
/** ************************画图部分********************************************************** */

/**
 * 初始化画图工具
 * @function
 * @property {Object<Interaction>} interactions - 初始化画图的交互工具
 * @property {String} pointStyle - 坐标点吸附在鼠标上的样式
 * @property {Style.Style} pointStyle - 画图时显示的点的样式
 * @property {Layer} pointLayer - 画图时显示点的图层,默认index为1010
 */
Zs.prototype._initDraw = function() {
  this.interactions = {};
  this.cursorUrl = config.style.drawImg.cursorUrl;
  this.pointStyle = new Style.Style({
    image: new Style.Icon({
      scale: config.style.drawImg.scale,
      size: config.style.drawImg.size,
      anchor: config.style.drawImg.anchor,
      src: config.style.drawImg.img
    })
  });
  if (!this.pointLayer) {
    this.pointLayer = new VectorLayer({
      source: new VectorSource()
    });

    this.pointLayer.setZIndex(1010);
    this.map.addLayer(this.pointLayer);
  }

  this._init = true;
};
/**
 * 画图完成时的回调
 * @callback Map~drawEnd
 * @param {Object} data - 画图完成时返回的数据集
 * @param {Layer} data.layer - 当前画图的图层
 * @param {String} data.geom - 当前图形边界的wkt值
 * @param {String} data.point - 当前图形中心的的wkt值
 */
/**
* 画图完成时的回调
* @callback Map~modifyEnd
* @param {Object} data - 画图完成时返回的数据集
* @param {Layer} data.layer - 当前画图的图层
* @param {String} data.geom - 当前图形边界的wkt值
* @param {String} data.point - 当前图形中心的的wkt值
*/
/**
 * 创建画图工具,同时添加交互工具,只有按住alt时才能修改图形
 * @param {Object} options - 创建画图工具时的配置
 * @param {Layer} [ptions.layer] - 画图的图层
 * @param {String} [options.fillColor = rgba(255,255,255,02)] - 设置图层的填充颜色
 * @param {String} [options.strokeColor = rgba(111,111,111,1)] - 设置图层的描边颜色
 * @param {Int} [options.strokeWidth = 2] - 设置图层的描边宽度
 * @param {String} [options.type = MultiLineString] - 设置画图的类型,包含:LineString,MultiLineString,Polygon,MultiPolygon,Circle
 * @param {Map~drawEnd} [options.drawEnd] - 画图完成时的回调
 * @param {Map~modifyEnd} [options.modifyEnd] - 修改画图时的回调
 */
Zs.prototype.initDraw = function(options) {
  options = options || {};
  !this._init && this._initDraw();

  if (this.interactions && this.interactions.layer) {
    if (options.layer) {
      this.map.removeLayer(this.interactions.layer);
    } else {
      options.layer = this.interactions.layer;
    }
  }
  this.pointLayer.getSource().clear();
  this.destoryDraw();

  var types = { MultiLineString: 'LineString', MultiPolygon: 'Polygon' }; // 将单个图形转为多个图形
  var layer = options.layer;

  var style = new Style.Style({
    fill: new Style.Fill({
      color: options.fillColor || 'rgba(255,255,255,0.2)'
    }),
    stroke: new Style.Stroke({
      width: parseFloat(options.strokeWidth) || 2,
      color: options.strokeColor || 'rgba(111,111,111,1)'
    })
  });

  if (!layer) {
    layer = new VectorLayer({
      source: new VectorSource(),
      style: style
    });
    this.map.addLayer(layer);
  }
  layer.setZIndex(1000);

  var draw = new Interaction.Draw({
    type: types[options.type] || options.type || 'MultiLineString',
    source: layer.getSource() // 注意设置source，这样绘制好的线，就会添加到这个source里

  });

  this.map.addInteraction(draw); // 添加画图交互功能
  this.interactions = {
    draw: draw,
    layer: layer,
    options: options
  };

  this._getInteractions();

  this.modifyEnd(this.interactions);
  this.drawStart(this.interactions);
  this.drawEnd(this.interactions);
};

/**
 * 添加画图交互功能
 */
Zs.prototype._getInteractions = function() {
  var that = this;
  var select = new Interaction.Select({
    filter: function(feature, _layer) {
      if (_layer === that.interactions.layer || _layer === that.pointLayer) { return true; }
    }
  });

  var modify = new Interaction.Modify({
    features: select.getFeatures()
    // condition: function (mapBrowserEvent) {
    //     return ol.events.condition.altKeyOnly(mapBrowserEvent);      //只有当按住alt键才能修改feature
    // }
  });

  // 平移中心点
  var translate = new Interaction.Translate({
    features: that.pointLayer.getSource().getFeaturesCollection(),
    layers: [that.pointLayer]
  });

  this.map.addInteraction(select); // 添加选中的交互功能
  this.map.addInteraction(modify); // 添加修改的交互功能
  this.map.addInteraction(translate); // 添加平移的交互功能

  this.interactions.select = select;
  this.interactions.modify = modify;
  this.interactions.translate = translate;
}

/**
 * 设置中心点时的回调
 * @callback Map~setCenter
 * @param {String} point - 中心点的数据
 * @param {ol.MapBrowserEvent} evt - 点击的事件对象
 */
/**
 * 设置中心的工具
 * @param {Map~setCenter} callback - 接收点击时返回的数据
 */
Zs.prototype.setCenter = function(callback) {
  !this._init && this._initDraw();
  var that = this;
  this.map.getTargetElement().style.cursor = this.cursorUrl;
  this.destoryDraw();
  this.pointLayer.getSource().clear();
  this._getInteractions();
  this.modifyEnd(this.interactions);
  this.map.once('click', function(evt) {
    var feature = that._addPoint(new Geom.Point(evt.coordinate));
    that.map.getTargetElement().style.cursor = 'default';
    callback && typeof (callback) === 'function' && callback(that.format.writeFeature(feature), evt);
  })
};
/**
 * 移除所有交互工具Interaction
 */
Zs.prototype.destoryDraw = function() {
  if (this.interactions) {
    this.interactions.draw && this.map.removeInteraction(this.interactions.draw);
    this.interactions.select && this.map.removeInteraction(this.interactions.select);
    this.interactions.modify && this.map.removeInteraction(this.interactions.modify);
    this.interactions.translate && this.map.removeInteraction(this.interactions.translate);
  }
};
/**
 * 初始化图形的编辑功能,将常用交互工具添加进地图
 * @param {Object} options - 初始化图形编辑时的配置
 * @param {Layer} options.layer - 承载图形的图层
 *
 */
Zs.prototype.initEdit = function(options) {
  !this._init && this._initDraw();
  this.interactions.options = options || {};
  var layer = this.interactions.layer || options.layer;
  // if (!layer) return false;
  this.interactions.layer = layer;

  this._getInteractions();

  this.modifyEnd(this.interactions);
};
/**
 * 画图前置操作,主要用于画圆时,清除前一次操作的数据
 * @private
 * @param {Object} interactions - 交互工具集合
 */
Zs.prototype.drawStart = function(interactions) {
  var that = this;
  interactions.draw && interactions.draw.on('drawend', function(event) {
    // event.feature 就是当前绘制完成的线的Feature
    if (interactions.options.type === 'Circle') {
      interactions.select.getFeatures().clear();
      interactions.layer.getSource().clear();
      that.pointLayer.getSource().clear();
    }
  });
};
/**
 *画图完成时的操作
 *@private
 */
Zs.prototype.drawEnd = function(interactions) {
  var that = this;

  interactions.draw && interactions.draw.on('drawend', function(event) {
    // event.feature 就是当前绘制完成的线的Feature
    var geometory = that._getDrawGeometry(event.feature, interactions, 'draw');
    var data = that._getDataFromGeometry(geometory);
    data.currentFeature = event.feature;
    data.layer = interactions.layer;

    interactions.select.getFeatures().clear(); // 画图完成，取消当前目标的选中状态

    interactions.options.drawEnd && typeof (interactions.options.drawEnd) === 'function' && interactions.options.drawEnd(data);
  });
};
/**
 * 画图完成后从当前图层取出数据
 * @private
 * @param {ol.Feature} feature - 当前画图的要素
 * @param {Object} interactions - 当前画图交互工具集合
 * @param {String} eventType - 当前数据处理方式
 * @returns {Geom} geom - 当前画图的数据集
 */
Zs.prototype._getDrawGeometry = function(feature, interactions, eventType) {
  var geom = null;
  if (!interactions.layer) return geom;
  var types = { LineString: 'MultiLineString', Polygon: 'MultiPolygon' }; // 将单个图形转为多个图形
  var geometry = feature.getGeometry();
  var type = geometry.getType();

  var flag = false; // 判断图层是否还有元素
  if (type === 'LineString' || type === 'Polygon') {
    geom = new Geom[types[type]]([]);
  } else {
    geom = geometry;
  }

  interactions.layer.getSource().forEachFeature(function(feature) {
    var geometry = feature.getGeometry();
    flag = true;

    if (geom['append' + type]) {
      if (geometry instanceof Geom.MultiPolygon) {
        geometry.getPolygons().forEach(function(v, k) {
          geom['append' + type](v);
        })
      }
      if (geometry instanceof Geom.Polygon) {
        geom['append' + type](geometry);
      }
    } else {
      geom = geometry;
    }
  });

  if (eventType === 'draw') {
    geom['append' + type] && geom['append' + type](geometry);
  } else if (!flag) {
    geom = null
  }

  return geom;
};
/**
 * 修改画图完成后的操作
 * @private
 */
Zs.prototype.modifyEnd = function(interactions) {
  var that = this;
  interactions.modify && interactions.modify.on('modifyend', function(event) {
    that.modifyEndFunc(event, interactions);
  })

  // 平移画图的方法
  interactions.translate && interactions.translate.on('translateend', function(event) {
    that.modifyEndFunc(event, interactions, false);
  })
};
/**
 * 修改画图完成后的操作的公共方法
 * @private
 */
Zs.prototype.modifyEndFunc = function(event, interactions, calcPoint) {
  var that = this;
  var data = {};
  var geometory = that._getDrawGeometry(event.features.item(0), interactions, 'modify');
  data = that._getDataFromGeometry(geometory, calcPoint);

  data.layer = interactions.layer;
  interactions.options && interactions.options.modifyEnd && typeof (interactions.options.modifyEnd) === 'function' && interactions.options.modifyEnd(data);
};
/**
 * 从geom中取出wkt数据及中心点
 * @private
 * @param {Geom} geometry
 */
Zs.prototype._getDataFromGeometry = function(geometry, calcPoint) {
  var data = {};
  if (!geometry) {
    data.geom = null;
  } else {
    var type = geometry.getType();
    if (type === 'Circle') {
      data.radius = geometry.getRadius();
    } else {
      data.geom = this.format.writeGeometry(geometry);
      if (data.geom === 'MULTIPOLYGON EMPTY') data.geom = null;
    }
  }

  var point = calcPoint === false ? this._getCenterData() : this._getCenterData(geometry);
  if (point) {
    data.point = this.format.writeGeometry(point);
    this._addPoint(point);
  } else {
    data.point = null;
    this.pointLayer.getSource().clear();
  }

  return data;
};

/**
 * 从获取当前画图图层的中心点
 * @private
 * @param {Geom} geometry
 */
Zs.prototype._getCenterData = function(geometry) {
  var point;
  if (geometry) {
    var type = geometry.getType();

    var getPoint = {
      MultiLineString: function() {
        return new Geom.Point(geometry.getFirstCoordinate());
      },
      LineString: function() {
        return new Geom.Point(geometry.getFirstCoordinate());
      },
      MultiPolygon: function() {
        var point = geometry.getInteriorPoints().getPoint(0);
        if (point) {
          var coordinates = point.getCoordinates();
          coordinates.pop();
          return new Geom.Point(coordinates);
        } else {
          return null
        }
      },
      Polygon: function() {
        var point = geometry.getInteriorPoint();
        if (point) {
          var coordinates = point.getCoordinates();
          coordinates.pop();
          return new Geom.Point(coordinates);
        } else {
          return null
        }
      },
      Circle: function() {
        return new Geom.Point(geometry.getCenter());
      }
    }

    if (getPoint[type]) {
      point = getPoint[type]();
    } else {
      throw type + '为无效类型!';
    }
  } else {
    point = this.pointLayer.getSource().getFeatures()[0].getGeometry();
  }
  return point;
}

/**
 * 向地图添加中心点
 * @private
 * @param {Geom} point - 中心点
 */
Zs.prototype._addPoint = function(point) {
  var feature = new ol.Feature(point)
  feature.setStyle(this.pointStyle);
  this.pointLayer.getSource().clear();
  this.pointLayer.getSource().addFeature(feature);
  return feature;
};
/**
 * 删除选中的要素
 * @private
 */
Zs.prototype.removeSelectedFeature = function() {
  var that = this;
  var feature;
  var data = {};
  if (this.interactions && this.interactions.select && this.interactions.layer) {
    // 图形选择不完整,forEach会报错
    this.interactions.select.getFeatures().forEach(function(v, k, arr) {
      feature = v.clone();
      that.interactions.layer.getSource().removeFeature(v);
    });
    this.interactions.select.getFeatures().clear();
    var geometory = that._getDrawGeometry(feature, that.interactions, 'delete');
    data = that._getDataFromGeometry(geometory);
    data.layer = this.interactions.layer;
    this.interactions.options.modifyEnd && typeof (this.interactions.options.modifyEnd) === 'function' && this.interactions.options.modifyEnd(data);
  }
  this.hideContextmenu();
};
/**
 * 初始化右键菜单,菜单主题div的class为:contextmenu_container
 */
Zs.prototype.initContextmenu = function() {
  // var that = this;
  this.menuOverlay = new ol.Overlay({
    element: document.querySelector('.contextmenu_container'),
    positioning: 'center-center'
  });
  this.menuOverlay.setMap(this.map);
//   $(this.map.getViewport()).on('contextmenu', function(e) {
//     e.preventDefault();
//     // 书写事件触发后的函数
//     var coordinate = that.map.getEventCoordinate(e);
//     that.menuOverlay.setPosition(coordinate);
//   });
//   $(this.map.getViewport()).on('click', function(e) {
//     e.preventDefault();
//     that.hideContextmenu();
//   });
};
Zs.prototype.hideContextmenu = function() {
  this.menuOverlay && this.menuOverlay.setPosition(undefined);
}

/**
 * 更新地图的底图显示状态
 */
Zs.prototype.switchMap = function() {
  var flag = !!this.showPlanimetric;
  this.planimetricLayers.forEach(function(v, k) {
    v.setVisible(flag);
  })
  this.satelliteLayers.forEach(function(v, k) {
    v.setVisible(!flag);
  })
}

Zs.prototype.switch25dMap = function() {
  if (this.show_25D && this._25DLayer) {
    if (this._25DLayer.getVisible()) {
      this._25DLayer.setVisible(false);
    } else {
      this._25DLayer.setVisible(true);
    }
  }
}

Zs.prototype._initMeasure = function(options) {
  options = options || {};
  this.map = options.map || this.map;
  this.wgs84Sphere = new olSphere(6378137);
  this.measureSketch; // 当前画的feature
  this.helpTooltipElement; // 提示元素
  this.helpTooltip; // 提示框{ol.Overlay}
  this.measureTooltipElement; // 测量提示元素
  this.measureTooltip; // 测量提示{ol.Overlay}
  this.continuePolygonMsg = '点击继续画测量多边形';
  this.continueLineMsg = '点击继续画测量线';
  this.measureHelpMsg = '点击开始测量';
  this.measureGeodesic = options.geodesic || false; // 按4326来测
  this.measureLayer = options.layer;
  !this.measureLayer && this.addMeasureLayer();
  // this.initMapMeasureEvents();
  this._initMeasure = false;
}
// 添加测量图层
Zs.prototype.addMeasureLayer = function() {
  var that = this;
  that.source = new VectorSource();
  that.measureLayer = new VectorLayer({
    source: that.source,
    style: new Style.Style({
      fill: new Style.Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Style.Stroke({
        color: '#ffcc33',
        width: 2
      }),
      image: new Style.Circle({
        radius: 7,
        fill: new Style.Fill({
          color: '#ffcc33'
        })
      })
    })
  });
  that.measureLayer.setZIndex(1000);
  that.map.addLayer(that.measureLayer);
}
Zs.prototype.initMapMeasureEvents = function() {
  var that = this;
  that.map.on('pointermove', function(evt) {
    if (evt.dragging) {
      return;
    }
    if (that.measureSketch) {
      var geom = (that.measureSketch.getGeometry());
      if (geom instanceof Geom.Polygon) {
        that.measureHelpMsg = that.continuePolygonMsg;
      } else if (geom instanceof Geom.LineString) {
        that.measureHelpMsg = that.continueLineMsg;
      }
    }
    if (that.helpTooltipElement) {
      that.helpTooltipElement.innerHTML = that.measureHelpMsg;
      that.helpTooltip.setPosition(evt.coordinate);
      that.helpTooltipElement.classList.remove('hidden');
    }
  });

  that.map.getViewport().addEventListener('mouseout', function() {
    that.helpTooltipElement.classList.add('hidden');
  });
}
Zs.prototype.formatLength = function(line) {
  var that = this;
  var length;
  if (that.measureGeodesic) {
    var coordinates = line.getCoordinates();
    length = 0;
    var sourceProj = that.map.getView().getProjection();
    for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
      var c1 = olProj.transform(coordinates[i], sourceProj, 'EPSG:4326');
      var c2 = olProj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');
      length += that.wgs84Sphere.haversineDistance(c1, c2);
    }
  } else {
    length = Math.round(line.getLength() * 100) / 100;
  }
  var output;
  if (length > 100) {
    output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km';
  } else {
    output = (Math.round(length * 100) / 100) + ' ' + 'm';
  }
  return output;
}
Zs.prototype.formatArea = function(polygon) {
  var that = this;
  var area;
  if (that.measureGeodesic) {
    var sourceProj = that.map.getView().getProjection();
    var geom = polygon.clone().transform(sourceProj, 'EPSG:4326');
    var coordinates = geom.getLinearRing(0).getCoordinates();
    area = Math.abs(that.wgs84Sphere.geodesicArea(coordinates));
  } else {
    area = polygon.getArea();
  }
  var output;
  if (area > 10000) {
    output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>';
  } else {
    output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>';
  }
  return output;
}
Zs.prototype.addMeasureInteraction = function(type) {
  var that = this;
  // that.addLayer();
  var draw = new Interaction.Draw({
    source: that.source,
    type: type,
    style: new Style.Style({
      fill: new Style.Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Style.Stroke({
        color: 'rgba(0, 0, 0, 0.5)',
        lineDash: [10, 10],
        width: 2
      }),
      image: new Style.Circle({
        radius: 5,
        stroke: new Style.Stroke({
          color: 'rgba(0, 0, 0, 0.7)'
        }),
        fill: new Style.Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        })
      })
    })
  });
  that.map.addInteraction(draw);
  return draw;
}
Zs.prototype.drawMeasureEvents = function(draw) {
  var that = this;
  var measureOptions = {
    classname: 'map-tooltip tooltip-measure',
    offset: [-25, -25],
    positioning: 'bottom-center'
  };
  // var helpOptions = {
  //   classname: 'map-tooltip hidden',
  //   offset: [15, 0],
  //   positioning: 'center-left'
  // };

  var mtip = this.createTooltip(measureOptions, this.measureTooltipElement);
  this.measureTooltipElement = mtip.element;
  this.measureTooltip = mtip.tooltip;
  // htip = tool.createTooltip(helpOptions,that.helpTooltipElement,that.helpTooltip);
  // that.helpTooltipElement = htip.element;
  // that.helpTooltip = htip.tooltip;
  var listener;
  draw.on('drawstart', function(evt) {
    that.measureSketch = evt.feature;
    var tooltipCoord = evt.coordinate;

    listener = that.measureSketch.getGeometry().on('change', function(evt) {
      var geom = evt.target;
      var output;
      if (geom instanceof Geom.Polygon) {
        output = that.formatArea(geom);
        tooltipCoord = geom.getInteriorPoint().getCoordinates();
      } else if (geom instanceof Geom.LineString) {
        output = that.formatLength(geom);
        tooltipCoord = geom.getLastCoordinate();
      }
      that.measureTooltipElement.innerHTML = output;
      that.measureTooltip.setPosition(tooltipCoord);
    });
  }, this);

  draw.on('drawend', function() {
    that.measureTooltipElement.className = 'map-tooltip tooltip-static';
    that.measureTooltip.setOffset([-25, -17]);
    that.measureSketch = null;
    that.measureTooltipElement = null;
    ol.Observable.unByKey(listener);
    that.map.removeInteraction(draw);
  }, this);
}
/**
 * 激活画线工具
 */
Zs.prototype.activeLineStringMeasure = function() {
  this._initMeasure && this._initMeasure();
  this.drawMeasureEvents(this.addMeasureInteraction('LineString'));
}
/**
 * 激活画面工具
 */
Zs.prototype.activePolygonMeasure = function() {
  this._initMeasure && this._initMeasure();
  this.drawMeasureEvents(this.addMeasureInteraction('Polygon'));
}

export {
  Zs
}
